#ifndef __MODELEDITOR_D3DCANVAS_H
#define __MODELEDITOR_D3DCANVAS_H



#include "../../JuceLibraryCode/JuceHeader.h"

class CMouseController : public D3D9Draggable3DOrientation
{
public:
	CMouseController() { m_MouseOffset.x = m_MouseOffset.y = 0; }
	~CMouseController() {}

    void setViewport (const juce::Rectangle<int>& newArea) noexcept
    {
        m_area = newArea;
    }
    template <typename Type>
    void mouseDown (const Point<Type>& mousePos) noexcept
    {
        m_lastMouse = mousePosToProportion (mousePos.toFloat());
		m_MouseOffset.x = 0;
		m_MouseOffset.y = 0;
    }

    template <typename Type>
    void mouseDrag (const Point<Type>& mousePos) noexcept
    {
		const float oldPos_x = m_lastMouse.x;
		const float oldPos_y = m_lastMouse.y;

        m_lastMouse = mousePosToProportion (mousePos.toFloat());

        const float newPos_x = m_lastMouse.x;
		const float newPos_y = m_lastMouse.y;

		m_MouseOffset.x = newPos_x - oldPos_x;
		m_MouseOffset.y = newPos_y - oldPos_y;        
    }

	Point<float> getPan() const noexcept
    {
        return m_MouseOffset;
    }

	void ResetPan() noexcept
	{
		m_MouseOffset.x = 0;
		m_MouseOffset.y = 0;
	}

private:
	Point<float> m_lastMouse;
	juce::Rectangle<int> m_area;
	Point<float> m_MouseOffset;

	Point<float> mousePosToProportion (const Point<float>& mousePos) const noexcept
    {
        const int scale = (jmin (m_area.getWidth(), m_area.getHeight()) / 2);

        // You must call setViewport() to give this object a valid window size before
        // calling any of the mouse input methods!
        jassert (scale > 0);

        return Point<float> ((mousePos.x - m_area.getCentreX()) / scale,
                             (m_area.getCentreY() - mousePos.y) / scale);
    }
};

//==============================================================================
class EditorD3DCanvas  :public Component,
						public D3D9Renderer
{

public:
    EditorD3DCanvas() : m_bNeedReset(false)
    {
        m_D3D9Context.setRenderer(this);
        m_D3D9Context.setComponentPaintingEnabled(false);
        m_D3D9Context.attachTo(*this);
    }

    ~EditorD3DCanvas()
    {
        m_D3D9Context.detach();
    }

	void DetachD3D9Context()
	{
		m_D3D9Context.detach();
	}

	// when the component creates a new internal context, this is called, and
    // we'll use the opportunity to create some images to use as textures.
    void newD3D9ContextCreated();
	void renderD3D9();
	void D3D9ContextClosing();

    void resized() 
	{ 
		draggablePan.setViewport(getLocalBounds());
		draggableOrientation.setViewport(getLocalBounds());
	}

	void mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel);
    void mouseDown (const MouseEvent& e);
    void mouseDrag (const MouseEvent& e);
    void paint (Graphics& ) 
	{

	}


	//==============================================================================
	void ResetDevice()
	{
		m_bNeedReset = true;
	}

private:
	void RenderModel(float fElapsedSeconds);
	void RenderCoordinateAxis(void);
	void RenderLableXYZ( float LableX_x, float LableX_y, float LableX_z,
		float LableY_x, float LableY_y, float LableY_z,
		float LableZ_x, float LableZ_y, float LableZ_z );
private:
    D3D9Context					m_D3D9Context;

    CMouseController			draggablePan;
	CMouseController			draggableOrientation;

	bool						m_bNeedReset;
 };

#endif
